package com.sutong.gateway.utils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.springframework.cloud.gateway.support.ServerWebExchangeUtils;
import org.springframework.core.io.buffer.NettyDataBuffer;
import org.springframework.http.MediaType;
import org.springframework.web.server.ServerWebExchange;

import java.nio.CharBuffer;
import java.nio.charset.StandardCharsets;

/**
 * 获取缓存的request body
 *
 * @author sutong
 * @date 2024-07-16 22:58
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class GatewayHttpUtil {

    public static String getRequestBody(ServerWebExchange exchange) {
        Object attribute = exchange.getAttribute(ServerWebExchangeUtils.CACHED_REQUEST_BODY_ATTR);
        if (attribute == null || !(attribute instanceof NettyDataBuffer)) {
            return null;
        }
        MediaType contentType = exchange.getRequest().getHeaders().getContentType();
        if (contentType != null && contentType.toString().contains(MediaType.MULTIPART_FORM_DATA_VALUE)) {
            return null;
        }
        NettyDataBuffer nettyDataBuffer = (NettyDataBuffer) attribute;
        CharBuffer charBuffer = StandardCharsets.UTF_8.decode(nettyDataBuffer.asByteBuffer());
        return charBuffer.toString();
    }



    /*
    // 获取请求体的另一种方式
    private Mono<Void> readRequestBody(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        return DataBufferUtils.join(request.getBody()).flatMap(dataBuffer -> {
            byte[] bytes = new byte[dataBuffer.readableByteCount()];
            dataBuffer.read(bytes);
            log.info("requestBody = {}", new String(bytes, StandardCharsets.UTF_8));
            DataBufferUtils.release(dataBuffer);
            Flux<DataBuffer> cachedFlux = Flux.defer(() -> Mono.just(exchange.getResponse().bufferFactory().wrap(bytes)));
            ServerHttpRequest mutatedRequest = new ServerHttpRequestDecorator(request) {
                @Override
                public Flux<DataBuffer> getBody() {
                    return cachedFlux;
                }
            };
            return chain.filter(exchange.mutate().request(mutatedRequest).build());
        });
    }
    */
}

